home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
ATUtilities.lha
/
ATUtilities
/
ASM
/
RDISK.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-09-26
|
23KB
|
372 lines
;**********************************************************************;
;* R A M D I S K *;
;*--------------------------------------------------------------------*;
;* Aufgabe : Dieses Programm ist ein Treiber fr eine 160KB *;
;* RAM-Disk. *;
;*--------------------------------------------------------------------*;
;* Autor : MICHAEL TISCHER *;
;* entwickelt am : 4.08.1987 *;
;* letztes Update : 2.11.1991 *;
;*--------------------------------------------------------------------*;
;* assemblieren : MASM RAMDISK; *;
;* LINK RAMDISK; *;
;* EXE2BIN RAMDISK RAMDISK.SYS oder *;
; *;
;* TASM RAMDISK *;
;* LINK RAMDISK; *;
;* EXE2BIN RAMDISK RAMDISK.SYS *;
;*--------------------------------------------------------------------*;
;* Aufruf : In das Hauptverzeichnis kopieren, den Befehl *;
;* DEVICE=RAMDISK.SYS in die Datei CONFIG.SYS *;
;* aufnehmen und dann System booten. *;
;**********************************************************************;
code segment
assume cs:code,ds:code,es:code,ss:code
org 0 ;Programm hat keinen PSP daher Anfang
;an der Offsetadresse 0
;== Konstanten =========================================================
befehl equ 2 ;Offset Befehls-Feld im Datenblock
status equ 3 ;Offset Status-Feld im Datenblock
anz_ger equ 13 ;Offset Anzahl untersttzter Gerte
wechsel equ 14 ;Offset Medium gewechselt?
end_adr equ 14 ;Offset Treiber End-Adr. im Datenblock
p_adr equ 14 ;Offset Puffer-Adresse im Datenblock
anz_bef equ 16 ;die Funktionen 0-16 werden untersttzt
anzahl equ 18 ;Offset Anzahl im Datenblock
bpb_adr equ 18 ;Offset Adresse des BPB des Medium
sektor equ 26 ;Offset erste Sektornummer
ger_bez equ 22 ;Offset Gerte-Bezeichnung der RAMDisk
;== Daten ==============================================================
erst_b equ this byte ;dies ist das erste Byte des Treibers
;-- Kopf des Gerte-Treibers -------------------------------------------
dw -1,-1 ;Verbindung zum nchsten Treiber
dw 0100100000000000b ;Treiber Attribut
dw offset strat ;Pointer auf Strategie-Routine
dw offset intr ;Pointer auf Interrupt-Routine
db 1 ;ein Gert wird untersttzt
db 7 dup (0) ;diese Bytes geben sonst den Namen an
;-- Sprungtabelle fr die einzelnen Funktionen -------------------------
fkt_tab dw offset init ;Funktion 0: Initialisierung
dw offset med_test ;Funktion 1: Medium Test
dw offset get_bpb ;Funktion 2: Erstelle BPB
dw offset lesen ;Funktion 3: direktes Lesen
dw offset lesen ;Funktion 4: Lesen
dw offset dummy ;Funktion 5: Lesen, im Puffer bleiben
dw offset dummy ;Funktion 6: Eingabe-Status
dw offset dummy ;Funktion 7: Lsche Eingabe-Puffer
dw offset schreibe ;Funktion 8: Schreiben
dw offset schreibe ;Funktion 9: Schreiben & Verifizieren
dw offset dummy ;Funktion 10: Ausgabe-Status
dw offset dummy ;Funktion 11: Lschen Ausgabe-Puffer
dw offset schreibe ;Funktion 12: direktes Schreiben
dw offset dummy ;Funktion 13: ffnen (diese Fkt ab 3.0)
dw offset dummy ;Funktion 14: Schlieáen
dw offset no_rem ;Funktion 15: wechselbares Medium?
dw offset schreibe ;Funktion 16: Ausgabe bis beschftigt
db_ptr dw (?),(?) ;Adresse des bergebenen Datenblocks
rd_seg dw (?) ;RD_SEG:0000 ist der Anfang der RAMDisk
bpb_ptr dw offset bpb,(?) ;Nimmt die Adresse des BPB auf
boot_sek db 3 dup (0) ;hier befindet sich noramlerweise ein
;Sprungbefehl zur Boot-Routine
db "MITI 1.0" ;Herstellername & Versionsnummer
bpb dw 512 ;512 Bytes pro Sektor
db 1 ;1 Sektoren pro Cluster
dw 1 ;1 reservierter Sektor (Boot-Sektor)
db 1 ;1 File-Allocation-Table (FAT)
dw 64 ;maximal 64 Eintrge im Hauptverz.
dw 320 ;insgesamt 320 Sektoren = 160 KB
db 0FEh ;Media Descriptor (1 Seite mit 40
;Spuren zu je 8 Sektoren)
dw 1 ;jede FAT belegt einen Sektor
;-- die Boot-Routine entfllt, da man ein System nicht ------
;-- von einer RAM-Disk booten kann
vol_name db "RAMDISK " ;der eigentliche Volume-Name
db 8 ;Attribut, definiert Volume-Name
;== Routinen und Funktionen des Treibers ===============================
strat proc far ;Strategie-Routine
mov cs:db_ptr,bx ;Adresse des Datenblocks in der
mov cs:db_ptr+2,es ;Variable DB_PTR merken
ret ;zurck zum Aufrufer
strat endp
;-----------------------------------------------------------------------
intr proc far ;Interrupt-Routine
push ax ;Register auf Stack sichern
push bx
push cx
push dx
push di
push si
push bp
push ds
push es
pushf ;auch das Flag-Register merken
push cs ;Datensegment-Register setzen
pop ds ;Code ist hier mit Daten identisch
les di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
mov bl,es:[di+befehl] ;Befehls-Code holen
cmp bl,anz_bef ;ist Befehls-Code erlaubt?
jle bc_ok ;JA --> bc_ok
mov ax,8003h ;Code fr "unbekannter Befehl"
jmp short intr_end ;zurck zum Aufrufer
;-- Befehls-Code war o.k. --> Befehl ausfhren ----------------
bc_ok: shl bl,1 ;Pointer in Sprungtabelle errechnen
xor bh,bh ;BH lschen
call [fkt_tab+bx] ;Funktion aufrufen
;-- Ausfhrung der Funktion beendet ---------------------------
intr_end label near
push cs ;Datensegment-Register setzen
pop ds ;Code ist hier mit Daten identisch
les di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
or ax,0100h ;Fertig-Bit setzen
mov es:[di+status],ax ;das ganze im Status-Feld abspeichern
popf ;Flag-Register zurckholen
pop es ;andere Register zurckholen
pop ds
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
ret ;zurck zum Aufrufer
intr endp
;-----------------------------------------------------------------------
init proc near ;Initialisierungs-Routine
;-- der folgende Code wird nach der Installation --------------
;-- von der eigentlichen RAMDisk berschrieben
;-- Gertebezeichnung der RAMDisk ermitteln -------------------
mov ah,30h ;DOS Version mit Hilfer der Fkt. 30(h)
int 21h ;des DOS-Interrupt 21(h) abfragen
cmp al,3 ;ist Version 3 oder hher?
jb prinm ;JA --> PRINM
mov al,es:[di+ger_bez] ;Gertebezeichnung holen
add al,"A" ;in Buchstaben umwandeln
mov im_ger,al ;in Installations-Meldung abspeichern
prinm: mov dx,offset initm ;Adresse der Installations-Meldung
mov ah,9 ;Funktionsnummer fr String ausgeben
int 21h ;DOS-Interrupt aufrufen
;-- Adresse des ersten Bytes hinter der RAMDisk berechen ------
;-- und als Endadresse des Treibers setzen
mov word ptr es:[di+end_adr],offset ramdisk+8000h
mov ax,cs ;die RAM-Disk ist 32KB plus
add ax,2000h ;2 * 64KB groá
mov es:[di+end_adr+2],ax
mov byte ptr es:[di+anz_ger],1 ;1 Gert wird unterst.
mov word ptr es:[di+bpb_adr],offset bpb_ptr ;Adresse des BPB-
mov es:[di+bpb_adr+2],ds ;Pointer
mov ax,cs ;Segmentadresse des Beginn der RAMDisk
mov bpb_ptr+2,ds ;Segmentadresse der BPB in BPB-Pointer
mov dx,offset ramdisk ;zur Offsetadresse 0 berechnen
mov cl,4 ;Offsetadresse durch 16 teilen und da-
shr dx,cl ;durch in Segmentadresse umrechnen
add ax,dx ;die beiden Segmentadressen addieren
mov rd_seg,ax ;und merken
;-- Boot-Sektor anlegen ---------------------------------------
mov es,ax ;Segmentadresse nach ES transferieren
xor di,di ;Boots. beginnt mit dem 1. Byte der RD
mov si,offset boot_sek ;Adresse des Boot-Sektor im Speicher
mov cx,15 ;nur die ersten 15 Words werden genutzt
rep movsw ;Boot-Sektor in RAMDisk kopieren
;-- die FAT anlegen -------------------------------------------
mov di,512 ;FAT beginnt mit dem Byte 512 der RD
mov al,0FEh ;Media-Descriptor in das erste Byte der
stosb ;FAT schreiben
mov ax,0FFFFH ;Code fr die Bytes 2 und 3 der FAT
stosw ;in FAT abpspeichern
mov cx,236 ;die restlichen 236 Word belegt die FAT
inc ax ;AX auf 0 setzen
rep stosw ;alle FAT-Eintrge auf unbelegt setzen
;-- das Hauptverzeichnis mit Volume-Namen anlegen -------------
mov di,1024 ;das Hauptverz. beginnt im 3. Sektor
mov si,offset vol_name ;Adresse des Volume-Namen im Speicher
mov cx,6 ;der Volume-Name ist 6 Words lang
rep movsw ;Volume-Namen in RD kopieren
mov cx,1017 ;den Rest des Directories in den Sektoren
xor ax,ax ;2, 3, 4 und 5 mit Nullen fllen
rep stosw
xor ax,ax ;alles o.k.
ret ;zurck zum Aufrufer
init endp
;-----------------------------------------------------------------------
dummy proc near ;diese Routine bewirkt nichts
xor ax,ax ;Beschftigt-Bit lschen
ret ;zurck zum Aufrufer
dummy endp
;-----------------------------------------------------------------------
med_test proc near ;das Medium der RAM-Disk kann nicht ge-
;wechselt werden
mov byte ptr es:[di+wechsel],1
xor ax,ax ;Beschftigt-Bit lschen
ret ;zurck zum Aufrufer
med_test endp
;-----------------------------------------------------------------------
get_bpb proc near ;Adresse des BPB an DOS bergeben
mov word ptr es:[di+bpb_adr],offset bpb
mov word ptr es:[di+bpb_adr+2],ds
xor ax,ax ;Beschftigt-Bit lschen
ret ;zurck zum Aufrufer
get_bpb endp
;-----------------------------------------------------------------------
no_rem proc near ;eine RAMDisk kann nicht gewechselt
;werden
mov ax,20 ;Beschftigt-Bit setzen
ret ;zurck zum Aufrufer
no_rem endp
;-----------------------------------------------------------------------
schreibe proc near
xor bp,bp ;bertragung DOS --> RAMDisk
jmp short move ;Daten kopieren
schreibe endp
;-----------------------------------------------------------------------
lesen proc near
mov bp,1 ;bertragung RAMDisk --> DOS
lesen endp
;-- MOVE: eine bestimmte Anzahl Sektoren zwischen RD und DOS verschieben
;-- Eingabe : BP = 0 : vom DOS zur RD bertragen (schreiben)
;-- 1 : von RD zum DOS bertragen (lesen)
;-- Ausgabe : keine
;-- Register : AX, BX, CX, DX, SI, DI, ES, DS und FLAGS werden verndert
;-- Info : die bentigten Informationen (Anzahl, erster Sektor)
;-- entnimmt diese Funktion dem vom DOS bergebenen Datenbl.
move proc near
mov bx,es:[di+anzahl] ;Anzahl der Sektoren lesen
mov dx,es:[di+sektor] ;Nummer des ersten Sektors
les di,es:[di+p_adr] ;Adresse des Puffers nach ES:DI
move_1: or bx,bx ;noch Sektoren lesen?
je move_e ;kein Sektor mehr --> ENDE
mov ax,dx ;Sektornummer nach AX
mov cl,5 ;Anzahl der Paragraphen (Segmentein-
shl ax,cl ;heiten) durch Multiplikation mit 32
;berechnen
add ax,cs:rd_seg ;und zum Segmentanfang der RD addieren
mov ds,ax ;nach DS bertragen
xor si,si ;Offsetadresse ist 0
mov ax,bx ;Anzahl zu lesende Sektoren nach AX
cmp ax,128 ;noch mehr als 128 Sektoren lesen
jbe move_2 ;NEIN --> alle Sektoren lesen
mov ax,128 ;JA --> 128 Sektoren (64 KB) lesen
move_2: sub bx,ax ;Anzahl der gelesenen Sektoren abziehen
add dx,ax ;auf nchsten zu lesenden Sek. addieren
mov ch,al ;Anzahl zu lesende Sektoren * 256 Words
xor cl,cl ;Lo-Byte des Word-Zhler auf 0 setzen
or bp,bp ;soll gelesen werden?
jne move_3 ;NEIN --> MOVE_3
mov ax,es ;ES in AX merken
push ds ;DS auf dem Stack merken
pop es ;als ES zurckholen
mov ds,ax ;ES und DS sind damit vertauscht
xchg si,di ;und SI und DI vertauschen
move_3: rep movsw ;Daten in den DOS-Puffer kopieren
or bp,bp ;soll gelesen werden?
jne move_1 ;NEIN --> evtl. weitere Sek. kopieren
mov ax,es ;ES in AX merken
push ds ;DS auf dem Stack merken
pop es ;als ES zurckholen
mov ds,ax ;ES und DS sind damit vertauscht
xchg si,di ;und SI und DI wieder zurcktauschen
jmp short move_1 ;evtl. weitere Sektoren kopieren
move_e: xor ax,ax ;alles o.k.
ret ;zurck zum Aufrufer
move endp
;-- ab hier beginnt die eigentliche RAMDisk ----------------------------
org ($-erst_b) + 16 - (($-erst_b) mod 16)
ramdisk equ this byte
initm db "**** 160 KB RAMDISK als Laufwerk "
im_ger db "?"
db ": installiert. (c) 1987,1991 by MICHAEL TISCHER$",13,10,10
;-----------------------------------------------------------------------
code ends
end